/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is Forte for Java, Community Edition. The Initial
* Developer of the Original Code is Sun Microsystems, Inc. Portions
* Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.autoupdate;
import java.net.URL;
import java.io.File;
import java.io.BufferedInputStream;
import java.util.*;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import org.w3c.dom.*;
import org.openide.loaders.XMLDataObject;
import org.openide.modules.ModuleDescription;
import org.openide.TopManager;
/** This class represents one module update available on the web
*
* @author phrebejk
* @version
*/
class ModuleUpdate extends Object
implements org.openide.nodes.Node.Cookie {
// Constants
private static final String NO = "NO"; // NOI18N
private static final String FALSE = "FALSE"; // NOI18N
private static final String ATTR_HOMEPAGE = "homepage"; // NOI18N
private static final String ATTR_MANIFEST = "manifest"; // NOI18N
private static final String ATTR_DISTRIBUTION = "distribution"; // NOI18N
private static final String ATTR_MANUFACTURER = "manufacturer"; // NOI18N
private static final String ATTR_DOWNLOAD_SIZE = "downloadsize"; // NOI18N
private static final String ATTR_UNPACKED_SIZE = "unpacksize"; // NOI18N
private static final String ATTR_LICENCE = "licence"; // NOI18N
private static final String ELEMENT_DESCRIPRION = "description"; // NOI18N
//private static LicenceCache licenceCache = new LicenceCache();
/** The base url of XML Document used to create URL from relative paths */
private URL xmlURL;
/** Node in the DOM the ModuleUpdate comes from */
private Node node;
/** Holds the document of the XML */
private Element documentElement;
/** Used for downloaded files */
private File nbmFile;
/** Holds value of property distribution. */
private URL distribution = null;
/** Holds value of property homepage. */
private URL homepage = null;
/** Holds value of property manifest. */
private URL manifest = null;
/** Holds value of property manufacturer. */
private String manufacturer = null;
/** Holds value of property downloadSize. */
private long downloadSize = -1;
/** Holds value of property unpackedSize. */
private long unpackedSize = -1;
/** Holds value of property downlaodOK. */
private boolean downloadOK = false;
/** Holds value of property description. */
private String description = null;
/** Holds value of property licence */
private String licenceID = null;
/** Holds value text of the licence */
private String licenceText = null;
/** Holds value of property selected */
private boolean selected = false;
/** Holds value of property secutiry */
private int security = SignVerifier.NOT_CHECKED;
/** Holds value of property certificates */
private Collection certs = null;
/** Holds value of property installApproved */
private boolean installApproved = false;
private boolean pError = false;
// Associations
private ModuleDescription localModule = null;
private ModuleDescription remoteModule = null;
//private Updates linearStructure;
// CONSTRUCTORS -------------------------------------------------------------
/** Creates new ModuleUpdate */
ModuleUpdate( URL xmlURL, Node node, Element documentElement ) {
this.xmlURL = xmlURL;
this.node = node;
this.documentElement = documentElement;
}
/** Creates new ModuleUpdate for downloaded .nbm file */
ModuleUpdate( File nbmFile ) {
this.nbmFile = nbmFile;
}
// METHODS ------------------------------------------------------------------
/** Reads the module update from DOM and if the module is already loaded
* finds the description
* @return True if the read-operation was O.K.
*/
boolean readModuleUpdate( ) {
// Read module update information
try {
String textURL = getAttribute( ATTR_HOMEPAGE );
if ( textURL != null )
homepage = new URL( xmlURL, textURL );
}
catch ( java.net.MalformedURLException e ) {
TopManager.getDefault().notifyException( e );
// let homepage set to null
}
setManufacturer( getAttribute( ATTR_MANUFACTURER ) );
try {
setDownloadSize( Long.parseLong( getAttribute( ATTR_DOWNLOAD_SIZE ) ) );
}
catch ( NumberFormatException e ) {
// Let the value set to -1
}
try {
setUnpackedSize( Long.parseLong( getAttribute( ATTR_UNPACKED_SIZE ) ) );
}
catch ( NumberFormatException e ) {
// Let the value set to -1
}
setDescription( getTextOfElement( ELEMENT_DESCRIPRION ) );
try {
String textURL = getAttribute( ATTR_DISTRIBUTION );
if ( textURL != null )
distribution = new URL ( xmlURL, textURL );
}
catch ( java.net.MalformedURLException e ) {
if (Boolean.getBoolean ("netbeans.debug.exceptions")) // NOI18N
e.printStackTrace ();
//TopManager.getDefault().notifyException( e );
// let distibution URL set to null
}
// Read the manifest from XML file and create
// the module description
try {
Manifest mf = manifestFromXML( );
remoteModule = new ModuleDescription( "temp", mf ); // NOI18N
}
catch ( org.openide.modules.IllegalModuleException e ) {
if (Boolean.getBoolean ("netbeans.debug.exceptions")) // NOI18N
e.printStackTrace ();
// let manifest URL set to null
}
// Read the licence from the XML
licenceID = getAttribute( ATTR_LICENCE );
licenceText = licenseFromXML( licenceID, documentElement );
/*
try {
String textURL = getAttribute( ATTR_LICENCE );
if ( textURL != null ) {
licenceURL = new URL( xmlURL, textURL );
String cachedText = licenceCache.getLicence( licenceURL );
if ( cachedText != null ) {
licenceText = cachedText; // licence already loaded
}
else {
BufferedInputStream bis = new BufferedInputStream( licenceURL.openStream() );
StringBuffer sb = new StringBuffer( 2000 );
int ch;
while( ( ch = bis.read() ) != -1 ) {
sb.append( (char)ch );
}
licenceText = sb.toString();
licenceCache.addLicence( licenceURL, licenceText );
}
}
}
catch ( java.net.MalformedURLException e ) {
if (Boolean.getBoolean ("netbeans.debug.exceptions"))
e.printStackTrace ();
//TopManager.getDefault().notifyException( e );
licenceURL = null;
licenceText = null;
}
catch ( java.io.IOException e ) {
if (Boolean.getBoolean ("netbeans.debug.exceptions"))
e.printStackTrace ();
//TopManager.getDefault().notifyException( e );
licenceURL = null;
licenceText = null;
}
*/
// Try to find installed module
ModuleDescription[] installedModules = Updates.getInstalledModules();
ModuleDescription[] installedPatches = Updates.getInstalledPatches();
if ( remoteModule != null ) {
// Try if the module describes the Core IDE
if ( remoteModule.getCodeName().equals( IdeDescription.getName() ) ) {
localModule = IdeDescription.getIdeDescription();
}
// Try other modules
for ( int i = 0; localModule == null && i < installedModules.length; i++ ) {
if ( installedModules[i].getCodeNameBase().equals( remoteModule.getCodeNameBase() ) ) {
localModule = installedModules[i];
break;
}
}
// Try wether the module is a installed patch
for ( int i = 0; localModule == null && i < installedPatches.length; i++ ) {
if ( installedPatches[i].getCodeNameBase().equals( remoteModule.getCodeNameBase() ) ) {
localModule = installedPatches[i];
break;
}
}
}
return remoteModule != null;
}
/** Creates module from downloaded .nbm file */
boolean createFromDistribution() {
Document document = null;
URL infoURL = null;
// Get the URL of the info file
try {
infoURL = new URL ( "jar:" + nbmFile.toURL().toString() + "!/Info/info.xml" ); // NOI18N
}
catch ( java.net.MalformedURLException e ) {
System.out.println( e );
}
// Try to parse the info file
try {
document = XMLDataObject.parse( infoURL, new ErrorCatcher() );
documentElement = document.getDocumentElement();
node = documentElement;
}
catch ( org.xml.sax.SAXException e ) {
if (Boolean.getBoolean ("netbeans.debug.exceptions")) { // NOI18N
System.out.println("Bad info : " + infoURL ); // NOI18N
//e.printStackTrace ();
}
return false;
//TopManager.getDefault().notifyException( e );
}
catch ( java.io.IOException e ) {
if (Boolean.getBoolean ("netbeans.debug.exceptions")) { // NOI18N
System.out.println("Missing info : " + infoURL ); // NOI18N
//e.printStackTrace ();
}
return false;
}
// Read module update information
try {
String textURL = getAttribute( ATTR_HOMEPAGE );
if ( textURL != null )
homepage = new URL( textURL );
}
catch ( java.net.MalformedURLException e ) {
TopManager.getDefault().notifyException( e );
// let homepage set to null
}
setManufacturer( getAttribute( ATTR_MANUFACTURER ) );
setDownloadSize( nbmFile.length() );
/*
try {
setDownloadSize( Long.parseLong( getAttribute( ATTR_DOWNLOAD_SIZE ) ) );
}
catch ( NumberFormatException e ) {
// Let the value set to -1
}
try {
setUnpackedSize( Long.parseLong( getAttribute( ATTR_UNPACKED_SIZE ) ) );
}
catch ( NumberFormatException e ) {
// Let the value set to -1
}
*/
setDescription( getTextOfElement( ELEMENT_DESCRIPRION ) );
// Read the manifest from XML file and create
// the module description
// Get the manifest file for the module
try {
Manifest mf = manifestFromXML( );
remoteModule = new ModuleDescription( "temp", mf ); // NOI18N
}
catch ( org.openide.modules.IllegalModuleException e ) {
if (Boolean.getBoolean ("netbeans.debug.exceptions")) // NOI18N
e.printStackTrace ();
// let manifest URL set to null
}
// Read the licence from the XML
licenceID = getAttribute( ATTR_LICENCE );
licenceText = licenseFromXML( licenceID, documentElement );
// Try to find installed module
ModuleDescription[] installedModules = Updates.getInstalledModules();
ModuleDescription[] installedPatches = Updates.getInstalledPatches();
if ( remoteModule != null ) {
// Try if the module describes the Core IDE
if ( remoteModule.getCodeName().equals( IdeDescription.getName() ) ) {
localModule = IdeDescription.getIdeDescription();
}
// Try other modules
for ( int i = 0; localModule == null && i < installedModules.length; i++ ) {
if ( installedModules[i].getCodeNameBase().equals( remoteModule.getCodeNameBase() ) ) {
localModule = installedModules[i];
break;
}
}
// Try wether the module is a installed patch
for ( int i = 0; localModule == null && i < installedPatches.length; i++ ) {
if ( installedPatches[i].getCodeNameBase().equals( remoteModule.getCodeNameBase() ) ) {
localModule = installedPatches[i];
break;
}
}
}
return remoteModule != null;
}
/** Finds the module in the Colloection of installed modules */
void resolveInstalledModule( Collection installedModules ) {
}
// GETTERS AND SETTERS ------------------------------------------------------
/** Getter for property codeNameBase.
*@return Value of property codeNameBase.
*/
String getCodeNameBase() {
return remoteModule.getCodeNameBase();
}
/** Getter for property name.
*@return Value of property name.
*/
String getName() {
return remoteModule.getName();
}
/** Getter for property distribution.
*@return Value of property distribution.
*/
URL getDistribution() {
return distribution;
}
/** Getter for property distributionFilename.
*@return Name of the distribution file.
*/
String getDistributionFilename() {
if ( nbmFile != null ) {
return nbmFile.getName();
}
else {
return new File( getDistribution().getFile() ).getName();
}
}
/** Getter for property licenceID.
*@return Value of property licenceID.
*/
String getLicenceID() {
return licenceID;
}
/** Getter for property manufacturer.
*@return Value of property manufacturer.
*/
public String getManufacturer() {
return manufacturer;
}
/** Setter for property manufacturer.
*@param manufacturer New value of property manufacturer.
*/
void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
/** Getter for property downloadSize.
*@return Value of property downloadSize.
*/
long getDownloadSize() {
return downloadSize;
}
/** Setter for property downloadSize.
*@param downloadSize New value of property downloadSize.
*/
void setDownloadSize(long downloadSize) {
this.downloadSize = downloadSize;
}
/** Getter for property unpackedSize.
*@return Value of property unpackedSize.
*/
long getUnpackedSize() {
return unpackedSize;
}
/** Setter for property unpackedSize.
*@param unpackedSize New value of property unpackedSize.
*/
void setUnpackedSize(long unpackedSize) {
this.unpackedSize = unpackedSize;
}
/** Getter for property description.
*@return Value of property description.
*/
String getDescription() {
return description;
}
/** Setter for property description.
*@param description New value of property description.
*/
void setDescription(String description) {
this.description = description;
}
/** Getter for property selected.
*@return Value of property selected.
*/
boolean isSelected() {
return selected;
}
/** Setter for property selected.
*@param description New value of property selected.
*/
void setSelected( boolean selected ) {
this.selected = selected;
}
/** Getter for property new.
*@return True if such module is not installed in netbeans
*/
boolean isNew() {
return localModule == null;
}
/** Getter for property homePage.
*@return Value of property homePage.
*/
URL getHomePage() {
return homepage;
}
/** Getter for property licenceText.
*@return Value of property licenceText.
*/
String getLicenceText() {
return licenceText;
}
/** Getter for property remoteModule.
*@return Value of property remoteModule.
*/
ModuleDescription getRemoteModule() {
return remoteModule;
}
/** Getter for property localModule.
*@return Value of property localModule.
*/
ModuleDescription getLocalModule() {
return localModule;
}
/** Tests if there is an update available */
boolean isUpdateAvailable() {
if ( getLocalModule() == null )
return true;
if ( getRemoteModule().getCodeNameRelease() > getLocalModule().getCodeNameRelease() ) {
return true;
}
try {
if ( !ModuleDescription.compatibleWith( getRemoteModule().getSpecVersion(), getLocalModule().getSpecVersion() ) ) {
return true;
}
}
catch ( org.openide.modules.IllegalModuleException e ) {
TopManager.getDefault().notifyException( e );
}
return false;
}
/** Getter for property downloadOK.
*@return Value of property downloadOK.
*/
boolean isDownloadOK() {
return downloadOK;
}
/** Setter for property downloadOK
*@param downloadOK New value of property downloadOK.
*/
void setDownloadOK( boolean downloadOK ) {
this.downloadOK = downloadOK;
}
/** Getter for property security.
*@return Value of property security.
*/
int getSecurity() {
return security;
}
/** Setter for property security
*@param downloadOK New value of property security.
*/
void setSecurity( int security ) {
this.security = security;
}
/** Getter for property certificates.
*@return Value of property certificates.
*/
Collection getCerts() {
return certs;
}
/** Setter for property certificates
*@param downloadOK New value of property certificates.
*/
void setCerts( Collection certs ) {
this.certs = certs;
}
/** Getter for property nbmFile.
*@return The manually downloaded nbm file.
*/
File getDistributionFile() {
return nbmFile;
}
/** Getter for property installApproved.
*@return Value of property installApproved.
*/
boolean isInstallApproved() {
return installApproved;
}
/** Setter for property installApproved.
*@param description New value of property installApproved.
*/
void setInstallApproved( boolean installApproved ) {
this.installApproved = installApproved;
}
// UTILITY METHODS ----------------------------------------------------------
/** Utility method gets the atribute of node
*@param attribute Name of the desired attribute
*/
private String getAttribute(String attribute) {
Node attr = node.getAttributes().getNamedItem( attribute );
return attr == null ? null : attr.getNodeValue();
}
/** Utility method gets text of subelement. Used for getting
* description text.
*@param name Name of the desired subelement
*/
private String getTextOfElement( String name ) {
if ( node.getNodeType() != Node.ELEMENT_NODE ||
!( node instanceof Element ) ) {
return null;
}
NodeList nodeList = ((Element)node).getElementsByTagName( name );
StringBuffer sb = new StringBuffer();
for( int i = 0; i < nodeList.getLength(); i++ ) {
if ( nodeList.item( i ).getNodeType() != Node.ELEMENT_NODE ||
!( nodeList.item( i ) instanceof Element ) ) {
break;
}
// ((Element)nodeList.item( i )).normalize();
NodeList innerList = nodeList.item( i ).getChildNodes();
for( int j = 0; j < innerList.getLength(); j++ ) {
if ( innerList.item( j ).getNodeType() == Node.TEXT_NODE ) {
sb.append( innerList.item( j ).getNodeValue() );
}
}
}
return sb.toString();
}
/** Utility methods finds the manifest tag, reads all it's attributes and
* creates the manifest */
private Manifest manifestFromXML() {
if ( node.getNodeType() != Node.ELEMENT_NODE ||
!( node instanceof Element ) ) {
return null;
}
NodeList nodeList = ((Element)node).getElementsByTagName( "manifest" ); // NOI18N
for( int i = 0; i < nodeList.getLength(); i++ ) {
if ( nodeList.item( i ).getNodeType() != Node.ELEMENT_NODE ||
!( nodeList.item( i ) instanceof Element ) ) {
break;
}
// ((Element)nodeList.item( i )).normalize();
NamedNodeMap attrList = nodeList.item( i ).getAttributes();
Manifest mf = new Manifest();
Attributes mfAttrs = mf.getMainAttributes();
for( int j = 0; j < attrList.getLength(); j++ ) {
Attr attr = (Attr) attrList.item( j );
mfAttrs.put( new Attributes.Name( attr.getName() ), attr.getValue() );
}
return mf;
}
return null;
}
/** Gets the licence from XML file
*/
private String licenseFromXML( String name, Element docElement ) {
NodeList nodeList = docElement.getElementsByTagName( "license" ); // NOI18N
for( int i = 0; i < nodeList.getLength(); i++ ) {
Node nameAttr = nodeList.item(i).getAttributes().getNamedItem( "name" ); // NOI18N
if ( nameAttr == null )
continue;
if ( nameAttr.getNodeValue().equals( name ) ) { // licence found
StringBuffer sb = new StringBuffer();
// ((Element)nodeList.item( i )).normalize();
NodeList innerList = nodeList.item( i ).getChildNodes();
for( int j = 0; j < innerList.getLength(); j++ ) {
if ( innerList.item( j ).getNodeType() == Node.TEXT_NODE ) {
sb.append( innerList.item( j ).getNodeValue() );
}
}
return sb.toString();
}
}
// licence not found
return null;
}
/* This innerclass represents licence cache
*/
/*
private static class LicenceCache extends Object {
private HashMap map;
LicenceCache() {
map = new HashMap();
}
String getLicence ( URL url ) {
Set keys = map.keySet();
Iterator it = keys.iterator();
while( it.hasNext() ) {
URL keyUrl = (URL)it.next();
if ( keyUrl.equals( url ) ) {
return (String)map.get( keyUrl );
}
}
return null;
}
void addLicence ( URL url, String text ) {
map.put( url, text );
}
}
*/
class ErrorCatcher implements org.xml.sax.ErrorHandler {
private void message (String level, org.xml.sax.SAXParseException e) {
pError = true;
}
public void error (org.xml.sax.SAXParseException e) {
// normally a validity error
pError = true;
}
public void warning (org.xml.sax.SAXParseException e) {
//parseFailed = true;
}
public void fatalError (org.xml.sax.SAXParseException e) {
pError = true;
}
} //end of inner class ErrorPrinter
}
/*
* Log
* 17 Gandalf 1.16 2/23/00 Petr Hrebejk Notifications added into
* autoupdate
* 16 Gandalf 1.15 1/13/00 Petr Hrebejk Multiuser bugfix
* 15 Gandalf 1.14 1/12/00 Petr Hrebejk i18n
* 14 Gandalf 1.13 12/20/99 Petr Hrebejk Autocheck & security
* finished
* 13 Gandalf 1.12 12/16/99 Petr Hrebejk Sign checking added
* 12 Gandalf 1.11 12/1/99 Petr Hrebejk Checkin signatures of
* NBM files & automatic autoupdate check added
* 11 Gandalf 1.10 11/11/99 Petr Hrebejk Download bug fix
* 10 Gandalf 1.9 11/9/99 Petr Hrebejk Better selection of nbm
* files
* 9 Gandalf 1.8 11/8/99 Petr Hrebejk Install of downloaded
* modules added, Licenses in XML
* 8 Gandalf 1.7 11/2/99 Petr Hrebejk Update made quicker.
* Manifests in XML file, Licence caching
* 7 Gandalf 1.6 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun
* Microsystems Copyright in File Comment
* 6 Gandalf 1.5 10/11/99 Petr Hrebejk Version before Beta 5
* 5 Gandalf 1.4 10/10/99 Petr Hrebejk AutoUpdate made to
* wizard
* 4 Gandalf 1.3 10/8/99 Petr Hrebejk Next development version
* 3 Gandalf 1.2 10/8/99 Petr Hrebejk Next Develop version
* 2 Gandalf 1.1 10/7/99 Petr Hrebejk Next development version
* 1 Gandalf 1.0 10/7/99 Petr Hrebejk
* $
*/